package com.tjdx.projectsubmission.service.impl;


import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tjdx.projectsubmission.db.entity.FillReport;
import com.tjdx.projectsubmission.db.entity.Section;
import com.tjdx.projectsubmission.db.mapper.SectionMapper;
import com.tjdx.projectsubmission.dto.FillReportDetailQueryDto;
import com.tjdx.projectsubmission.dto.FillReportListDto;
import com.tjdx.projectsubmission.dto.FillReportQueryDto;
import com.tjdx.projectsubmission.dto.FillReportSaveDto;
import com.tjdx.projectsubmission.db.entity.FillReportDetail;
import com.tjdx.projectsubmission.db.mapper.FillReportDetailMapper;
import com.tjdx.projectsubmission.db.mapper.FillReportMapper;
import com.tjdx.projectsubmission.server.CollapseSet;
import com.tjdx.projectsubmission.service.FillReportService;
import com.tjdx.projectsubmission.util.DateUtil;
import com.tjdx.projectsubmission.util.RequestUserUtil;
import com.tjdx.projectsubmission.util.SubmitUtil;
import com.tjdx.projectsubmission.vo.R;
import com.tjdx.projectsubmission.vo.fill.FileReportListVo;
import com.tjdx.projectsubmission.vo.report.ReportQueryVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

@Slf4j
@Service
@Transactional
public class FillReportServiceImpl implements FillReportService {

    @Autowired
    private FillReportMapper fillReportMapper;

    @Autowired
    private FillReportDetailMapper fillReportDetailMapper;

    @Autowired
    private RequestUserUtil requestUserUtil;

    @Autowired
    private SectionMapper sectionMapper;


    /**
     * 保存工程填报 提交
     *
     * @param fillReportSaveDto
     * @return
     */
    @Override
    public R saveReport(FillReportSaveDto fillReportSaveDto) {
        try {
//            FillReportQueryDto dto = new FillReportQueryDto();
//            dto.setFillRepTime(fillReportSaveDto.getFillRepTime());
//            dto.setSectionId(dto.getSectionId());
//            dto.setCurMilNum(fillReportSaveDto.getCurMilNum());
//            FileReportListVo oneReport = fillReportMapper.getOneReport(dto);
//            if (oneReport != null) {
//                return 0;
//            }
            Integer userId = requestUserUtil.getUserId();
            if (userId == null) {
                return R.error("当前登录用户失效，请重新登录！");
            }
            fillReportSaveDto.setUserId(String.valueOf(userId));
            int insertNum = fillReportMapper.insert(fillReportSaveDto);
            List<FillReportDetail> reportDetails = new ArrayList<>();
//            if (insertNum > 0) {
                // 添加详情
                Long id = fillReportSaveDto.getId();
                reportDetails = fillReportSaveDto.getReportDetails();
                if (reportDetails.size() > 0) {
                    for (FillReportDetail reportDetail : reportDetails) {
                        reportDetail.setFillDetailPid(id);
                    }
                }
                int detailsNum = fillReportDetailMapper.BatchInsert(reportDetails);
//            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return R.ok();
    }


    /**
     * 获取此用户当前是否存在填报
     *
     * @param fillReportQueryDto
     * @return
     */
    @Override
    public FileReportListVo getOneReport(FillReportQueryDto fillReportQueryDto) {
//        fillReportQueryDto.setUserId(requestUserUtil.getUserId().toString());
        FileReportListVo oneReport = fillReportMapper.getOneReport(fillReportQueryDto);
        if (ObjectUtils.isNotEmpty(oneReport)) {
            Long id = oneReport.getId();
            // 根据ID转换 标段
            Long sectionId = oneReport.getSectionId();
            Section section = sectionMapper.selectByPrimaryKey(sectionId);
            oneReport.setSectionName(section.getName());

            List<FillReportDetailQueryDto> details = fillReportDetailMapper.selectFillChild(id);
            oneReport.setReportDetails(details);
        }
        return oneReport;
    }


    @Override
    public R auditing(Long id) {
        // 先查询还有没有 未确认的项目。
        FillReport fillReport = fillReportMapper.selectByPrimaryKey(id);
        List<FillReportDetailQueryDto> details = fillReportDetailMapper.selectFillChild(id);

        Map<String,String> nodeStates = new HashMap<>();

        if (details.size() > 0) {
            for (FillReportDetailQueryDto detail : details) {
                //  是否通过  1：确认  2：驳回
                if (detail.getIsAdopt() == 2) {
                    return R.error().message("提交失败,还有未确认的节点！");
                }
                nodeStates.put(detail.getCode(), detail.getState());
            }

            // 这里提交并生成风险等级
            String X1 = nodeStates.get("X1");
            String X2 = nodeStates.get("X2");
            String X3 = nodeStates.get("X3");
            String X4 = nodeStates.get("X4");
            String X5 = nodeStates.get("X5");
            String X6 = nodeStates.get("X6");
            String X7 = nodeStates.get("X7");
            String X8 = nodeStates.get("X8");
            String X9 = nodeStates.get("X9");
            String X10 = nodeStates.get("X10");
            String X11 = nodeStates.get("X11");
            String X12 = nodeStates.get("X12");
            String X13 = nodeStates.get("X13");
            String X14 = nodeStates.get("X14");
            String X15 = nodeStates.get("X15");
            String X16 = nodeStates.get("X16");
            String T = nodeStates.get("T");

            // 调用 CollapseSet.run 方法
            Map<String, Object> dataMap = CollapseSet.run(X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15, X16);
            int riskLevel = (Integer) dataMap.get("riskLevel");
            double pm1 = (Double)dataMap.get("pM1");
            double pm2 = (Double)dataMap.get("pM2");

            // 更新表
            fillReport.setRiskLevel(riskLevel);
            fillReport.setPm1(BigDecimal.valueOf(pm1));
            fillReport.setPm2(BigDecimal.valueOf(pm2));
            fillReportMapper.updateById(fillReport);
        }
        return R.ok();
    }


    /**
     * 查询填报列表
     *
     * @param fillReportListDto
     * @return
     */
    @Override
    public IPage<FileReportListVo> getAllReport(FillReportListDto fillReportListDto) {

        Long pageNum = fillReportListDto.getPageNum();
        Long pageSize = fillReportListDto.getPageSize();
        Page page = new Page(pageNum, pageSize);

        IPage<FileReportListVo> reportIPage = fillReportMapper.getAllReport(page, fillReportListDto);
        List<FileReportListVo> records = reportIPage.getRecords();
        for (FileReportListVo record : records) {
            // // 根据ID转换 标段
            // Long sectionId = record.getSectionId();
            // Section section = sectionMapper.selectByPrimaryKey(sectionId);
            // record.setSectionName(section.getName());
            // 查询子列表
            List<FillReportDetailQueryDto> details = fillReportDetailMapper.selectFillChild(record.getId());
            record.setReportDetails(details);

        }
        return reportIPage;
    }


    @Override
    public R reportSubmit(Long id,Long riskLevel) {
        FillReport fillReport = fillReportMapper.selectByPrimaryKey(id);

        FileReportListVo reportListVo = new FileReportListVo();
        if (ObjectUtils.isNotEmpty(fillReport)) {
            List<FillReportDetailQueryDto> details = fillReportDetailMapper.selectFillChild(id);
            reportListVo.setReportDetails(details);
            reportListVo.setId(fillReport.getId());
            reportListVo.setFillRepTime(fillReport.getFillRepTime());
            reportListVo.setCurMilNum(fillReport.getCurMilNum());
            reportListVo.setUserId(fillReport.getUserId());
            reportListVo.setReviewStatus(fillReport.getReviewStatus());
            reportListVo.setIsUpload(fillReport.getIsUpload());

            // 校验通过，调用上传梧桐连接口
            String data = JSONObject.toJSONString(fillReport);
            if (StringUtils.isBlank(data) || "null".equals(data)) {
                return R.error().message("参数错误");
            }
            log.info("填报页数据提交接口 - data:[{}]", data);

            //区块链交易id
            String dataId = SubmitUtil.submitBlockchain(data);
//            String dataId = "123456456456456";
//            if (StringUtils.isBlank(data) || "null".equals(data)) {
//                return R.error().message("参数错误");
//            }
            log.info("区块链交易id - data:[{}]", dataId);
//            // 将区块哈希保存
//            if (riskLevel > 0) {
//                fillReport.setIsUpload(1);
//            }
            fillReportMapper.updateById(fillReport);
        }
        return R.ok();
    }


    @Override
    public List<ReportQueryVo> list() {
        QueryWrapper<FillReport> wrapper = new QueryWrapper<>();
        wrapper.orderByAsc("fill_rep_time");
        List<FillReport> reportList = fillReportMapper.selectList(wrapper);
        List<ReportQueryVo> resList = new ArrayList<>();

        for (FillReport fillReport : reportList) {
            Long id = fillReport.getId();
            List<FillReportDetailQueryDto> fillReportDetailQueryDtos = fillReportDetailMapper.selectFillChild(id);

            ReportQueryVo queryVo = new ReportQueryVo();

            Date fillRepTime = fillReport.getFillRepTime();
            String quarter = DateUtil.quarter(DateUtil.getMM(fillRepTime));
            int weeks = DateUtil.getWeek(fillRepTime);
            String year = DateUtil.getSysYear(fillRepTime);
            String dateStr = year + "年第" + quarter + "季度第" + weeks + "周";

            queryVo.setDateStr(dateStr);
            for (FillReportDetailQueryDto detailQueryDto : fillReportDetailQueryDtos) {

                queryVo.setNodeName(detailQueryDto.getNodeName());
                queryVo.setState(detailQueryDto.getState());
                queryVo.setInfoSource(detailQueryDto.getInfoSource());
                queryVo.setIsConfirm(detailQueryDto.getIsConfirm());
                queryVo.setBlockHash(detailQueryDto.getBlockHash());
                resList.add(queryVo);
            }
        }
        return resList;
    }


}
